package cn.hn.java.summer.db;

import java.util.List;

/**
 * Created by xw2sy on 2017-05-22.
 */
public class Oql {

    private BaseDao baseDao;

    private OqlData oqlData;


    protected Oql(BaseDao baseDao){
        this.baseDao=baseDao;
        oqlData=new OqlData();
    }

    /**
     * 设置参数
     * @param paras 参数列表
     * @return oql
     */
    public Oql paras(Object ...paras){
        oqlData.setParas(paras);
        return this;
    }

    /***
     * 设置sqlid
     * @param sqlId sql编号
     * @return oql
     */
    public Oql sqlId(String sqlId){
        oqlData.setSqlId(sqlId);
        return this;
    }

    /**
     * 按字段升序
     * @param colName 字段名
     * @return oql
     */
    public Oql ascBy(String colName){
        OrderBy orderBy= oqlData.getOrderBy();
        if(orderBy==null){
            orderBy=new OrderBy();
            oqlData.setOrderBy(orderBy);
        }
        orderBy.asc(colName);
        return this;
    }

    /**
     * 按字段降序
     * @param colName 字段名
     * @return oql
     */
    public Oql descBy(String colName){
        OrderBy orderBy= oqlData.getOrderBy();
        if(orderBy==null){
            orderBy=new OrderBy();
            oqlData.setOrderBy(orderBy);
        }
        orderBy.desc(colName);
        return this;
    }

    /**
     * 按字段排序
     * @param colName 字段名
     * @param asc 是否为升序
     * @return oql
     */
    public Oql orderBy(String colName, boolean asc){
        if(asc){
            return ascBy(colName);
        }
        return descBy(colName);
    }

    /**
     * 取列表结果，可根据请求参数决定是否分页
     * @param cls 返回list中对象类型class
     * @param <T> 返回list中对象类型
     * @return T类型的列表
     */
    public <T> List<T> list(Class<T> cls){
        //不传sqlId时，根据自动映射生成的sql进行查询
        if(oqlData.getSqlId()==null){
            //带排序的查询
            if(oqlData.getOrderBy()!=null) {
                return baseDao.list(cls,oqlData.getOrderBy(),oqlData.getParas());
            }
            return baseDao.list(cls, oqlData.getParas());
        }
        //使用sqlId进行查询
        return baseDao.list(oqlData.getSqlId(),cls,oqlData.getParas());
    }

    /**
     * 取查询的所有结果，不分页
     * @param cls 返回list中对象类型class
     * @param <T> 返回list中对象类型
     * @return T类型的列表
     */
    public <T> List<T> all(Class<T> cls){
        //不传sqlId时，根据自动映射生成的sql进行查询
        if(oqlData.getSqlId()==null){
            //带排序的查询
            if(oqlData.getOrderBy()!=null) {
                return baseDao.all(cls,oqlData.getOrderBy(),oqlData.getParas());
            }
            return baseDao.all(cls, oqlData.getParas());
        }
        //使用sqlId进行查询
        return baseDao.all(oqlData.getSqlId(),cls,oqlData.getParas());
    }

    /**
     * 使用sqlId或主键查询一条记录的对象
     * @param cls 返回对象类型class
     * @param <T> 对象类型
     * @return T类型的对象
     */
    public <T> T one(Class<T> cls){
        //不传sqlId时，根据自动映射生成的sql进行查询
        if(oqlData.getSqlId()==null){
            return (T) baseDao.get(cls,oqlData.getParas());
        }
        return (T) baseDao.get(oqlData.getSqlId(),cls,oqlData.getParas());
    }

    /**
     * 使用sqlId或bean新增一条记录
     * @param bean 新增的对象信息
     * @param <T> 对象类型
     * @return 影响行数
     */
    public <T> int insert(T bean){
        //不传sqlId时，根据自动映射生成的sql进行insert
        if(oqlData.getSqlId()==null && bean!=null){
            return baseDao.insert(bean);
        }
        assert (oqlData.getSqlId()!=null);
        //使用sqlId调用通用的update方法添加记录
        return update(bean);
    }

    /**
     * 新增一条记录，新增的数据不只是一个bean通过paras传送时
     * @return 影响行数
     */
    public int insert(){
        return insert(null);
    }

    /**
     * 使用sqlId或主键更新记录
     * @param bean 更新对象信息
     * @param <T> 对象类型
     * @return 影响行数
     */
    public <T> int update(T bean){
        //不传sqlId时，根据自动映射生成的sql进行更新
        if(oqlData.getSqlId()==null && bean!=null){
            return baseDao.update(bean);
        }
        assert (oqlData.getSqlId()!=null);
        Object[] paras;
        if(bean==null){
            paras=oqlData.getParas();
        }else {
            //将不为空的bean作为参数添加进去
            paras=new Object[oqlData.getParas().length+1];
            paras[0]=bean;
            for (int i=0; i< oqlData.paras.length; i++){
                paras[i+1]=oqlData.paras[i];
            }
        }
        //使用sqlId调用通用的update方法更新或添加
        return baseDao.update(oqlData.getSqlId(),paras);
    }

    /**
     * 使用sqlId更新记录，当更新的数据不只是一个bean通过paras传送时
     * @return 影响行数
     */
    public int update(){
        return update(null);
    }

    /**
     * 根据主键或对象数据删除记录
     * @param bean 删除数据条件
     * @param <T> 删除对象类型
     * @return 影响行数
     */
    public <T> int delete(T bean){
        if(oqlData.getSqlId()==null && bean!=null) {
            return baseDao.delete(bean);
        }
        assert (oqlData.getSqlId()!=null);
        //使用sqlId调用通用的update方法删除
        return update(bean);
    }

    class OqlData{
        //参数列表
        private Object[] paras;
        //sqlId
        private String sqlId;
        //排序
        private OrderBy orderBy;

        public Object[] getParas() {
            return paras;
        }

        public void setParas(Object[] paras) {
            this.paras = paras;
        }

        public String getSqlId() {
            return sqlId;
        }

        public void setSqlId(String sqlId) {
            this.sqlId = sqlId;
        }

        public OrderBy getOrderBy() {
            return orderBy;
        }

        public void setOrderBy(OrderBy orderBy) {
            this.orderBy = orderBy;
        }
    }

}
